// 版权所有2011 Go作者。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package net

import (
	"os"
	"syscall"
)

func setDefaultSockopts(s syscall.Handle, family, sotype int, ipv6only bool) error {
	if family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW {
		// 允许两个IP版本，即使操作系统默认的
		// 不是这样。请注意，有些操作系统
		// 从不接受此选项。允许广播。
		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
	}
	if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX && family != syscall.AF_INET6 {
		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
	}
	return nil
}

func setDefaultListenerSockopts(s syscall.Handle) error {
	// 默认情况下，Windows将重用最近使用的地址。
	// SO_REUSEADDR不应该在这里使用，因为它允许一个套接字强制绑定到另一个套接字正在使用的端口。
	// 这可能会导致一种不确定性行为，即无法保证端口上的连接请求由正确的套接字处理。
	return nil
}

func setDefaultMulticastSockopts(s syscall.Handle) error {
	// 允许多播UDP和原始IP数据报套接字跨多个侦听器同时侦听
	// 。
	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1))
}
